﻿#include "ComServerManage.h"
#include <QApplication>
#include "TcpServer.h"
#include <QSettings>


#pragma execution_character_set("utf-8")
ComServerManage::ComServerManage(QObject *parent)
    : QObject{parent}
{
    //setConfigWriteOneFunc(void (*func)(const TcpComConfig& config));
    //setConfigReadAllFunc(QMap<QString, TcpComConfig> (*func)());
    //setConfigReadOneFunc(TcpComConfig (*func)(QString camName));
    //initWgtComServerStatus();
    //initComServerManageWidget();
    //initComServerAll();
    //startWorker();
#if QT_VERSION >= 0x060000
// Qt 6 的代码
#else
    // Qt 5 的代码
    qRegisterMetaTypeStreamOperators<TcpComConfig>("TcpComConfig");
#endif

    configWriteOne = [](const TcpComConfig& config){
        QSettings iniFile(QApplication::applicationDirPath() + "/Config.ini", QSettings::IniFormat);
        iniFile.setValue("TcpComConfig/" + config.name, QVariant::fromValue(config));
    };
    configReadOne = [](QString name)->TcpComConfig{
        QSettings iniFile(QApplication::applicationDirPath() + "/Config.ini", QSettings::IniFormat);
        TcpComConfig config = iniFile.value("TcpComConfig/" + name).value<TcpComConfig>();
        return config;
    };
    configReadAll = []()->QMap<QString, TcpComConfig>{
        QSettings iniFile(QApplication::applicationDirPath() + "/Config.ini", QSettings::IniFormat);
        iniFile.beginGroup("TcpComConfig");
        QStringList keyList = iniFile.childKeys();
        QMap<QString, TcpComConfig> mapConfig;
        for(auto key : keyList){
            TcpComConfig config = iniFile.value(key).value<TcpComConfig>();
            mapConfig.insert(config.name, config);
        }
        iniFile.endGroup();
        return mapConfig;
    };
}

void ComServerManage::setConfigWriteOneFunc(void (*func)(const TcpComConfig& config))
{
    configWriteOne = func;
}
void ComServerManage::setConfigReadAllFunc(QMap<QString, TcpComConfig> (*func)())
{
    configReadAll = func;
}
void ComServerManage::setConfigReadOneFunc(TcpComConfig (*func)(QString camName))
{
    configReadOne = func;
}
void ComServerManage::startWorker()
{
    for(auto thread : mMapComThread.values()){
        thread->start();
    }
}
void ComServerManage::checkComServerStatus()
{
    bool isStart = true;
    if(mMapComStart.size() != mMapComServer.size()){
        isStart = false;
        goto checkEnd;
    }
    for(auto status : mMapComStart.values()){
        if(!status){
            isStart = false;
            break;
        }
    }
checkEnd:
    emit sigComServerStatus(isStart);
}
void ComServerManage::initComServerAll()
{
    QMap<QString, TcpComConfig> mapComConfig = configReadAll();
    for(auto key : mapComConfig.keys()){
        initComServerOne(mapComConfig.value(key));
    }
}
void ComServerManage::initComServerOne(TcpComConfig config)
{
    TcpServer* comWorker = new TcpServer();
    comWorker->setConfig(config);
    mMapComServer.insert(config.name, comWorker);

    QThread* comThread = new QThread();
    mMapComThread.insert(config.name, comThread);

    comWorker->moveToThread(comThread);
    connect(comThread, &QThread::started, comWorker, &TcpServer::onInit);
    connect(qApp, &QApplication::aboutToQuit, comWorker, &TcpServer::onQuit);
    connect(comWorker, &QObject::destroyed, comThread, &QThread::quit);
    connect(comThread, &QThread::finished, comThread, &QThread::deleteLater);

    wgtComServerStatus->addOne(config.name);

    //在相机管理页面添加一个
    mComServerManageWidget->addComServer(mMapComServer.value(config.name));

    //连接相机的状态信号，并显示
    QString comName = config.name;
    connect(comWorker, &TcpServer::sigStateChanged, this, [&, comName](const ComState& status){
        wgtComServerStatus->setStatus(comName, TcpServer::mapServerStateLabel.value(status));
    });

}
void ComServerManage::initWgtComServerStatus()
{
    wgtComServerStatus = new ComServerStatusWidget();
    wgtComServerStatus->setMinimumWidth(200);
}
void ComServerManage::initComServerManageWidget()
{
    mComServerManageWidget = new WidgetComServer("相机调试");
    connect(mComServerManageWidget, &WidgetComServer::sigAddOne, this, &ComServerManage::onAddOne);
    connect(mComServerManageWidget, &WidgetComServer::sigConfigChanged, this, &ComServerManage::onConfigChanged);
    connect(mComServerManageWidget, &WidgetComServer::sigDeleteOne, this, &ComServerManage::onDeleteOne);
}
void ComServerManage::onAddOne(const TcpComConfig& config)
{
    if(mMapComServer.contains(config.name))
        return;
    configWriteOne(config);
    initComServerOne(config);
    mMapComThread.value(config.name)->start();
}
void ComServerManage::onDeleteOne(const QString& name)
{
    if(!mMapComServer.contains(name))
        return;
    TcpServer* com = mMapComServer.take(name);
    com->deleteLater();
    com = nullptr;
    wgtComServerStatus->removeOne(name);
}
void ComServerManage::onConfigChanged(const TcpComConfig& config)
{
    configWriteOne(config);
}
